import axios from 'axios'
import { getBaseURL } from '@/utils/request'

// 文件类型映射
const FILE_TYPE_MAP = {
  // 文本文件
  text: ['.txt', '.md', '.json', '.xml', '.csv', '.log', '.js', '.css', '.html', '.vue', '.ts', '.jsx', '.tsx', '.yml', '.yaml', '.ini', '.conf'],
  // 图片文件
  image: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg', '.ico'],
  // PDF文件
  pdf: ['.pdf'],
  // Office文档
  office: ['.xlsx', '.xls', '.docx', '.doc', '.pptx', '.ppt'],
  // 视频文件
  video: ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm', '.m4v'],
  // 音频文件
  audio: ['.mp3', '.wav', '.ogg', '.aac', '.flac', '.m4a', '.wma']
}

// 文件大小限制（字节）
const FILE_SIZE_LIMITS = {
  text: 10 * 1024 * 1024,    // 10MB
  image: 50 * 1024 * 1024,   // 50MB
  pdf: 100 * 1024 * 1024,    // 100MB
  office: 100 * 1024 * 1024, // 100MB
  video: 500 * 1024 * 1024,  // 500MB
  audio: 100 * 1024 * 1024   // 100MB
}

/**
 * 根据文件后缀获取文件类型
 * @param {string} fileSuffix - 文件后缀名
 * @returns {string} 文件类型
 */
export function getFileType(fileSuffix) {
  if (!fileSuffix) return 'unknown'
  
  const suffix = fileSuffix.toLowerCase()
  for (const [type, extensions] of Object.entries(FILE_TYPE_MAP)) {
    if (extensions.includes(suffix)) {
      return type
    }
  }
  return 'unknown'
}

/**
 * 判断文件是否可预览
 * @param {string} fileSuffix - 文件后缀名
 * @param {number} fileSize - 文件大小（字节）
 * @returns {boolean} 是否可预览
 */
export function isPreviewable(fileSuffix, fileSize = 0) {
  const fileType = getFileType(fileSuffix)
  if (fileType === 'unknown') return false
  
  // 检查文件大小限制
  const sizeLimit = FILE_SIZE_LIMITS[fileType]
  if (fileSize > sizeLimit) return false
  
  return true
}

/**
 * 获取文件预览URL
 * @param {string} fileId - 文件ID
 * @param {string} fileType - 文件类型
 * @returns {string} 预览URL
 */
export function getPreviewUrl(fileId, fileType) {
  const baseUrl = getBaseURL()
  
  switch (fileType) {
    case 'text':
      return `${baseUrl}/api/files/content/${fileId}`
    case 'image':
    case 'video':
    case 'audio':
    case 'pdf':
      return `${baseUrl}/api/files/stream/${fileId}`
    case 'office':
      // 使用微软Office Online预览服务
      const fileUrl = encodeURIComponent(`${baseUrl}/api/files/stream/${fileId}`)
      return `https://view.officeapps.live.com/op/embed.aspx?src=${fileUrl}`
    default:
      return ''
  }
}

/**
 * 下载文件内容（用于文本文件）
 * @param {string} fileId - 文件ID
 * @returns {Promise<string>} 文件内容
 */
export async function downloadFileContent(fileId) {
  try {
    const response = await axios.get(`/api/files/content/${fileId}`, {
      headers: {
        'token': localStorage.getItem('token')
      },
      responseType: 'text'
    })
    return response.data
  } catch (error) {
    throw new Error('获取文件内容失败: ' + error.message)
  }
}

/**
 * 获取文件预览信息
 * @param {string} fileId - 文件ID
 * @returns {Promise<Object>} 预览信息
 */
export async function getFilePreviewInfo(fileId) {
  try {
    const response = await axios.get(`/api/files/preview/${fileId}`, {
      headers: {
        'token': localStorage.getItem('token')
      }
    })
    return response.data
  } catch (error) {
    throw new Error('获取文件预览信息失败: ' + error.message)
  }
}

/**
 * 格式化文件大小
 * @param {number} bytes - 字节数
 * @returns {string} 格式化后的文件大小
 */
export function formatFileSize(bytes) {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 获取文件图标类名
 * @param {string} fileSuffix - 文件后缀名
 * @returns {string} 图标类名
 */
export function getFileIcon(fileSuffix) {
  const fileType = getFileType(fileSuffix)
  const iconMap = {
    text: 'Document',
    image: 'Picture',
    pdf: 'Document',
    office: 'Document',
    video: 'VideoPlay',
    audio: 'Headphone',
    unknown: 'Files'
  }
  return iconMap[fileType] || 'Files'
}

/**
 * 检查文件是否为安全类型（防止XSS）
 * @param {string} fileSuffix - 文件后缀名
 * @returns {boolean} 是否安全
 */
export function isSafeFileType(fileSuffix) {
  const dangerousTypes = ['.exe', '.bat', '.cmd', '.com', '.scr', '.vbs', '.js', '.jar']
  return !dangerousTypes.includes(fileSuffix.toLowerCase())
}

/**
 * 生成文件下载URL
 * @param {string} fileId - 文件ID
 * @returns {string} 下载URL
 */
export function getDownloadUrl(fileId) {
  const baseUrl = getBaseURL()
  return `${baseUrl}/api/files/download/${fileId}`
}